/**
 * Created by TamTT on 1/13/14.
 * FPT University - Da Nang
 * Capstone project - group 3
 * Jornee
 */
module.exports.controller = function(app, jwt, secret, db, authentication, util, connect, cookie, randomstring, smtpTransport, passwordHash, log, colors, s3Client){
	/**
	 * Import modules
	 */
	var fs = require('fs');
	var multiparty = require('multiparty');
	var crypto = require('crypto');
	var graphicsmagick = require('gm');
	var gm = graphicsmagick.subClass({
		imageMagick: true
	});

	/**
	 * Register - ThanhND
	 */
	app.post('/register', function(req, res){
		var username = req.body.id;
		var password = passwordHash.generate(req.body.pass, {
			algorithm: 'sha512'
		});
		var email = req.body.email;

		db.users.findOne({
			"email": email
		}, function(err, doc){
			if(err){
				log.error('Register - Error with %s'.red, err);
				res.send({
					status: "error"
				});
			}
			if(doc){
				log.warning('Register - Email existed'.yellow);
				res.send({
					status: "email"
				});
			} else {
				db.users.findOne({
					"username": username
				}, function(err, doc){
					if(err){
						log.error('Register - Error with %s'.red, err);
						res.send({
							status: "error"
						});
					}
					if(doc){
						log.warning('Register - Username existed'.yellow);
						res.send({
							status: "id"
						});
					} else {
						var info = {
							username: username,
							date: new Date()
						};
						var first_token = jwt.encode(info, secret);
						db.users.insert({
							"username": username,
							"password": password,
							"authentication": first_token,
							"email": email,
							"avatar": '1.jpg',
							"dob": '',
							"gender": '',
							"chat_id": '',
							"following": [],
							"follower": [],
							"host": false,
							"create_date": new Date().toISOString(),
							"modified_date": '',
							"outside": []
						}, function(err){
							if(err){
								log.error('Register - Error with %s'.red, err);
								res.send({
									status: "error"
								});
							} else {
								log.info('Register - OK'.blue);
								res.send({
									status: "true"
								});
							}
						});
					}
				});
			}
		});
	});

	/**
	 * Login
	 */
	app.post('/login', function(req, res){
		var username = req.body.username;
		var password = req.body.password;
		db.users.findOne({
			"username": username
		}, function(err, doc){
			if(err){
				log.error('Login - Error with %s'.red, err);
				res.send({
					status: "error"
				});
			}
			if(!doc){
				log.info('Login - Fail'.blue);
				res.send({
					status: "fail"
				});
			} else {
				if(passwordHash.verify(password, doc.password)){
					var info = {
						username: username,
						date: new Date()
					};
					var new_token = jwt.encode(info, secret);
					db.users.update({
						username: username
					}, {
						$set: {
							authentication: new_token
						}
					});
					log.info('Login - User % - OK'.blue, username);
					res.send({
						status: "ok",
						token: new_token,
						username: doc.username,
						avatar: doc.avatar,
						is_host: doc.host
					});
				} else {
					log.info('Login - Fail'.blue);
					res.send({
						status: "fail"
					});
				}
			}
		});
	});

	/**
	 * Reset password - ThanhND
	 */
	app.post('/reset_password', function(req, res){
		var email = req.body.email;
		db.users.findOne({
			email: email
		}, function(err, doc){
			if(err){
				log.error('Reset password - Error with %s'.red, err);
				res.send({
					status: "error"
				});
			} else {
				if(doc){
					var password = randomstring.generate(8);
					var message = "Your new password: <b>" + password + "</b>. Please should change your password after login. ";
					db.users.update({
						email: email
					}, {
						$set: {
							password: passwordHash.generate(password, {
								algorithm: 'sha512'
							})
						}
					}, function(err){
						if(err){
							log.error('Reset password - Error with %s'.red, err);
							res.send({
								status: 'error'
							});
						} else {
							smtpTransport.sendMail({
								from: "Jornee <jornee.4t1c@gmail.com>", // sender address
								to: email, // comma separated list of receivers
								subject: "New password for jornee", // Subject line
								html: message // plaintext body
							});
							log.info('Reset password - OK'.blue);
							res.send({
								status: "ok"
							});
						}
					});
				} else {
					log.warning('Reset password - Email invalid'.yellow);
					res.send({
						status: "fail"
					});
				}
			}
		});
	});

	/**
	 * Logout - ThanhND
	 */
	app.post('/logout', function(req, res){
		var token = req.body.token;
		db.users.findOne({
			authentication: token
		}, function(err, result){
			if(err){
				log.error('Logout - Error with %s'.red, err);
				res.send({
					status: "error"
				});
			} else if(result == null){
				log.info('Logout - OK'.blue);
				res.send({
					status: "ok"
				});
			} else {
				db.users.update({
					authentication: token
				}, {
					$unset: {
						authentication: ""
					}
				}, function(err){
					if(err){
						log.error('Logout - Error with %s'.red, err);
						res.send({
							status: "error"
						});
					} else {
						log.info('Logout - OK'.blue);
						res.send({
							status: "ok"
						});
					}
				});
			}
		});
	});

	/**
	 * Change password - ThanhND
	 */
	app.post('/change_password', function(req, res){
		authentication(req, function(result){
			if(result.loginStatus == 'error'){
				res.send({
					authen_status: 'error'
				});
			} else if(result.loginStatus == 'false'){
				res.send({
					authen_status: 'fail'
				});
			} else if(result.loginStatus == 'true'){
				/**
				 * Code begin
				 */
				var old_pass = req.body.old_pass;
				var new_pass = req.body.new_pass;
				db.users.findOne({
					username: result.login_user
				}, function(err, doc){
					if(err){
						log.error('Change password - User %s - Error with %s'.red, result.login_user, err);
						res.send({
							authen_status: 'ok',
							status: 'error'
						});
					} else {
						if(passwordHash.verify(old_pass, doc.password)){
							db.users.update({
								username: result.login_user
							}, {
								$set: {
									password: passwordHash.generate(new_pass, {
										algorithm: 'sha512'
									})
								}
							}, function(err){
								if(err){
									log.error('Change password - User %s - Error with %s'.red, result.login_user, err);
									res.send({
										authen_status: 'ok',
										status: 'error'
									});
								} else {
									log.info('Change password - User %s - OK'.blue, result.login_user);
									res.send({
										authen_status: 'ok',
										status: 'ok'
									});
								}
							});
						} else {
							log.warning('Change password - User %s - Old password invalid'.yellow, result.login_user);
							res.send({
								authen_status: 'ok',
								status: 'fail'
							});
						}
					}
				});
			}
		});
	});

	/**
	 * Upload avatar  - ThanhND
	 */
	app.post('/upload_avatar', function(req, res){
		if(app.is_deploy){
			var form = new multiparty.Form();
		} else {
			var form = new multiparty.Form({
				uploadDir: "./users_data"
			});
		}
		form.on('error', function(err){
			if(err){
				log.error('Upload avatar - Error with %s'.red, err);
			}
			res.send({
				authen_status: 'ok',
				status: 'error'
			});
		});
		form.on('part', function(part){
			var type = part.headers['content-type'];
			if(type){
				type = type.split('/');
				type = type[1];
				if(type != 'jpeg' && type != 'png' && type != 'jpg'){
					this.emit('error');
				}
			}
		});
		form.on('file', function(name, file){
			//console.log("file: " + name + " " + file.headers);
		});
		form.on('field', function(name, value){
			//console.log("field: " + name + " " + value);
		});
		form.parse(req, function(err, fields, files){
			var request = {};
			request.body = {};
			var file = files.upload[0];
			var type = file.headers['content-type'];
			type = type.split('/');
			type = type[1];
			if(type == 'jpeg'){
				type = 'jpg';
			}
			request.body.token = fields.token[0];
			authentication(request, function(result){
				if(result.loginStatus == 'error'){
					res.send({
						authen_status: 'error'
					});
				} else if(result.loginStatus == 'false'){
					res.send({
						authen_status: 'fail'
					});
				} else if(result.loginStatus == 'true'){
					/**
					 * Code begin
					 */
					//Username: result.login_user
					var my_id = result.login_user;
					var path = './users_data/images/';
					var algorithm = 'aes256'; // or any other algorithm supported by OpenSSL
					var info = {
						date: new Date()
					};
					var cipher = crypto.createCipher(algorithm, secret);
					var filename = cipher.update(my_id, 'utf8', 'hex') + cipher.final('hex') + "_" + jwt.encode(info, secret);
					if(app.is_deploy){ //In deploy environment
						var headers = {
							'x-amz-acl': 'public-read'
						};
						headers['Content-Length'] = files.upload[0].size;
						s3Client.putFile(file.path, '/images/original/' + filename + '.' + type, function(err, s3Response){
							if(err) throw err;
						});
						//Resize
						var img = gm(file.path);
						img.size(function(err, size){
							if(err) throw err;
							if(!err){
								if(size.width >= size.height){
									img.resize(666);
									img.write('/tmp/' + filename + '.' + type, function(err){
										if(err) log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
										s3Client.putFile('/tmp/' + filename + '.' + type, '/images/medium/' + filename + '.' + type, function(err, s3Response){
											if(err){
												log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
												throw err;
											}
										});
									});
									img.resize(206);
									img.write('/tmp/' + filename + '.' + type, function(err){
										if(err) log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
										s3Client.putFile('/tmp/' + filename + '.' + type, '/images/thumbnail/' + filename + '.' + type, function(err, s3Response){
											if(err){
												log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
												throw err;
											}
										});
									});
								} else {
									img.resize(null, 666);
									img.write('/tmp/' + filename + '.' + type, function(err){
										if(err) log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
										s3Client.putFile('/tmp/' + filename + '.' + type, '/images/medium/' + filename + '.' + type, function(err, s3Response){
											if(err){
												log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
												throw err;
											}
										});
									});
									img.resize(null, 206);
									img.write('/tmp/' + filename + '.' + type, function(err){
										if(err) log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
										s3Client.putFile('/tmp/' + filename + '.' + type, '/images/thumbnail/' + filename + '.' + type, function(err, s3Response){
											if(err){
												log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
												throw err;
											}
										});
									});
								}
							}
						});
					} else { //Not in deploy environment
						fs.renameSync('./' + file.path, path + 'original/' + filename + '.' + type);
						//Resize
						var img = gm(path + 'original/' + filename + '.' + type);
						img.size(function(err, size){
							if(err) throw err;
							if(!err){
								if(size.width >= size.height){
									img.resize(666);
									img.write('./users_data/images/medium/' + filename + '.' + type, function(err){
										if(err){
											log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										}
									});
									img.resize(206);
									img.write('./users_data/images/thumbnail/' + filename + '.' + type, function(err){
										if(err){
											log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										}
									});
								} else {
									img.resize(null, 666);
									img.write('./users_data/images/medium/' + filename + '.' + type, function(err){
										if(err){
											log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										}
									});
									img.resize(null, 206);
									img.write('./users_data/images/thumbnail/' + filename + '.' + type, function(err){
										if(err){
											log.error('Upload avatar - User %s - error with %s'.red, result.login_user, err);
											res.send({
												authen_status: 'ok',
												status: 'error'
											});
										}
									});
								}
							}
						});
					}
					db.users.update({
						username: result.login_user
					}, {
						$set: {
							avatar: filename + '.' + type,
							modified_date: new Date().toISOString()
						}
					}, function(err){
						if(err){
							log.error('Upload avatar - User %s - Error with %s'.red, result.login_user, err);
							res.send({
								authen_status: 'ok',
								status: 'error'
							});
						} else {
							log.info('Upload avatar - User %s - OK'.blue, result.login_user);
							res.send({
								authen_status: 'ok',
								status: 'ok'
							});
						}
					})
				}
			});
		});
	});

	/**
	 * Edit profile - ThanhND
	 */
	app.post('/edit_profile', function(req, res){
		authentication(req, function(result){
			if(result.loginStatus == 'error'){
				res.send({
					authen_status: 'error'
				});
			} else if(result.loginStatus == 'false'){
				res.send({
					authen_status: 'fail'
				});
			} else if(result.loginStatus == 'true'){
				/**
				 * Code begin
				 */
				var email = req.body.email;
				var birthday = req.body.birthday;
				var gender = req.body.gender;
				db.users.findOne({
					username: result.login_user,
					email: email
				}, function(err, doc){
					if(err){
						log.error('Edit profile - User %s - Error with %s'.red, result.login_user, err);
						res.send({
							authen_status: 'ok',
							status: 'error'
						});
					}
					if(doc){
						db.users.update({
							username: result.login_user
						}, {
							$set: {
								gender: gender,
								dob: birthday,
								modified_date: new Date().toISOString()
							}
						}, function(err){
							if(err){
								log.error('Edit profile - User %s - Error with %s'.red, result.login_user, err);
								res.send({
									authen_status: 'ok',
									status: 'error'
								});
							} else {
								log.info('Edit profile - User %s - OK'.blue, result.login_user);
								res.send({
									authen_status: 'ok',
									status: 'ok'
								});
							}
						})
					} else {
						db.users.findOne({
							email: email
						}, function(err, doc){
							if(err){
								log.error('Edit profile - User %s - Error with %s'.red, result.login_user, err);
								res.send({
									authen_status: 'ok',
									status: 'error'
								});
							}
							if(doc){
								log.warning('Edit profile - User %s - New email was registered to another account'.yellow);
								res.send({
									authen_status: 'ok',
									status: 'email'
								});
							} else {
								db.users.update({
									username: result.login_user
								}, {
									$set: {
										email: email,
										gender: gender,
										dob: birthday,
										modified_date: new Date().toISOString()
									}
								}, function(err){
									if(err){
										log.error('Edit profile - User %s - Error with %s'.red, result.login_user, err);
										res.send({
											authen_status: 'ok',
											status: 'error'
										});
									} else {
										log.info('Edit profile - User %s - OK'.blue, result.login_user);
										res.send({
											authen_status: 'ok',
											status: 'ok'
										});
									}
								})
							}
						})
					}
				})
			}
		});
	});
};